package ynu.edu.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import ynu.edu.auth.domain.UserRole;
import ynu.edu.auth.mapper.MenuMapper;
import ynu.edu.auth.mapper.UserRoleMapper;
import ynu.edu.auth.service.PermissionService;
import ynu.edu.common.constant.PermissionConstants;
import ynu.edu.common.utils.RedisCache;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class PermissionServiceImpl implements PermissionService {


    private final UserRoleMapper userRoleMapper;
    private final MenuMapper menuMapper;
    private final RedisCache redisCache;

    @Value("${ynu.system.default-role:2}") // 从配置读取，默认角色id(1为管理员、2为普通用户)
    private Long defaultRoleId;


    /**
     * 根据用户id获取权限
     * @param userId
     * @return
     */
    @Override
    public List<String> getPermissions(Long userId) {
        String cacheKey = PermissionConstants.PERMISSION_CACHE_PREFIX + userId;
        // 1. 带空值缓存的查询
        List<String> perms = redisCache.getCacheObject(cacheKey);
        if (perms != null && !perms.isEmpty()) {
            return perms; // 返回null保持原有逻辑
        }

        // 2. 合并查询（减少数据库访问次数）
        List<String> dbPerms = menuMapper.selectPermsByUserId(userId);

        // 3.缓存到Redis
        if (dbPerms.isEmpty()){
            //  缓存空值
            redisCache.setCacheObject(cacheKey, Collections.emptyList(), Duration.ofSeconds(30));
        }else {
            // 缓存数据
            // 有效数据缓存2小时（添加随机偏移防止雪崩）
            Duration ttl = Duration.ofHours(2)
                    .plusMinutes(new Random().nextInt(10));
            redisCache.setCacheObject(cacheKey, dbPerms, ttl);
        }
        return dbPerms;
    }

    /**
     * 根据用户id获取角色
     * @param userId
     * @return
     */
    @Override
    public List<String> getRoles(Long userId) {
        List<Long> user_role = userRoleMapper.selectList(
                new LambdaQueryWrapper<UserRole>()
                        .eq(UserRole::getUserId, userId)
        ).stream().map(UserRole::getRoleId).collect(Collectors.toList());

        return user_role.stream().map(String::valueOf).collect(Collectors.toList());
    }

    /**
     * 为用户分配默认角色
     * @param userId
     */
    @Override
    public void assignDefaultRole(Long userId) {

        // 检查是否已存在该角色分配
        int count = userRoleMapper.selectCount(new LambdaQueryWrapper<UserRole>()
                .eq(UserRole::getUserId, userId)
                .eq(UserRole::getRoleId, defaultRoleId));

        if(count > 0) {
            log.info("用户[{}]已拥有默认角色[{}]，跳过分配", userId, defaultRoleId);
            return;
        }

        UserRole userRole = new UserRole();
        userRole.setUserId(userId);
        userRole.setRoleId(defaultRoleId);
        userRoleMapper.insert(userRole);

        // 清除权限缓存
        redisCache.deleteObject(PermissionConstants.PERMISSION_CACHE_PREFIX + userId);
        log.info("已为用户[{}]分配默认角色[{}]", userId, defaultRoleId);
    }
}
